package net.easyjava.framework.third.elasticsearch;

import net.easyjava.framework.utils.ProjectProperties;
import net.easyjava.third.search.elastic.ESearchClient;
import net.easyjava.third.search.elastic.bean.RangeBean;
import net.easyjava.tools.page.Page;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wenxiaoning on 16/6/18.
 */
public class ESearchUtils {
    private static Logger logger = LoggerFactory.getLogger(ESearchUtils.class);
    private static ESearchClient client;
    static {
        if(client == null){
            init();
        }
    }
    private static synchronized void init(){
        if(client == null){
            ProjectProperties properties = ProjectProperties.getInstance();
            String clusterName = properties.getProperty("esearch.cluster.name");
            String ips = properties.getProperty("esearch.ips");
            String ports = properties.getProperty("esearch.ports");
            try {
                client = ESearchClient.getInstance(clusterName,ips,ports);
            } catch (UnknownHostException e) {
                logger.error("ESearch 初始化失败 clusterName:{} ips:{} ports:{}",clusterName,ips,ports);
                logger.error(e.getMessage(),e.fillInStackTrace());
            }
        }
    }



    /**
     * 删除索引
     * @param indexName
     * @param type
     * @param id
     * @return
     */
    public static boolean deleteIndex(String indexName,String type,String id){
        try {
            DeleteResponse deleteResponse = client.deleteIndex(indexName, type, id);
            return deleteResponse.isFound();
        }catch (Exception e){
            logger.error("删除索引失败 indexName:{} type:{} id:{}",indexName,type,id);
            logger.error(e.getMessage(),e.fillInStackTrace());
        }
        return false;
    }

    /**
     * 批量删除
     * @param indexName
     * @param type
     * @param ids
     * @return
     */
    public static boolean deleteIndex(String indexName,String type,List<String> ids){
        try {
            BulkResponse bulkResponse = client.bulkDeleteIndex(indexName,type,ids);
            return !bulkResponse.hasFailures();
        }catch (Exception e){
            logger.error("批量删除索引失败 indexName:{} type:{} ids:{}",indexName,type,ids);
            logger.error(e.getMessage(),e.fillInStackTrace());
        }
        return false;
    }

    /**
     * 读取索引
     * @param id
     * @return
     */
    public static <T> T  getIndex(String id,Class<T> clazz){
        try {
            return client.getIndex(id, clazz);
        }catch (Exception e){
            logger.error("获取索引失败 id:{} clazz:{}",id,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
        }
        return null;
    }

    /**
     * 批量生成索引
     * @param indexName
     * @param type
     * @param source
     * @return
     */
    public static boolean createIndex(String indexName,String type,String id,String source){
        try {
            IndexResponse response = client.createIndex(indexName, type, id, source);
            if(response.isCreated()){
                return true;
            }
        } catch (Exception e) {
            logger.error("创建索引失败 indexName:{} type:{} id:{} source:{}",
                    indexName,type,id,source);
            logger.error(e.getMessage(), e.fillInStackTrace());
            return false;
        }
        return false;
    }
    public static boolean createIndex(String indexName,String type,Object object){
        try {
            IndexResponse response = client.createIndex(indexName, type, object);
            if(response.isCreated()){
                return true;
            }
        } catch (Exception e) {
            logger.error("创建索引失败 indexName:{} type:{} object:{}",
                    indexName,type,object);
            logger.error(e.getMessage(), e.fillInStackTrace());
            return false;
        }
        return false;
    }

    public static <T> boolean createIndex(String indexName,String type,List<T> objects){
        BulkResponse bulkResponse = null;
        try {
            bulkResponse = client.bulkCreateIndex(indexName, type, objects);
            if(bulkResponse.hasFailures()){
                logger.error("创建索引失败 message:{}",bulkResponse.buildFailureMessage());
                return false;
            }else{
                return true;
            }
        }catch (Exception e){
            logger.error("创建索引失败 indexName:{} type:{} ",indexName,type);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return false;
        }
    }

    /**
     * 创建索引
     * @param object
     * @return
     */
    public static boolean createIndex(Object object){
        try {
            IndexResponse response = client.createIndex(object);
            if(response.isCreated()){
                return true;
            }
        } catch (Exception e) {
            logger.error("创建索引失败 params:{}",object.toString());
            logger.error(e.getMessage(), e.fillInStackTrace());
            return false;
        }
        return false;
    }

    /**
     * 批量创建索引
     * @param list
     * @param <T>
     * @return
     */
    public static <T> boolean createIndex(List<T> list){
        try {
            BulkResponse response = client.bulkCreateIndex(list);
            if(!response.hasFailures()){
                return true;
            }else{
                logger.error("创建索引失败 message:{}",response.buildFailureMessage());
                return false;
            }
        } catch (Exception e) {
            logger.error("批量创建索引失败");
            logger.error(e.getMessage(), e.fillInStackTrace());
            return false;
        }
    }

    /**
     * 搜索
     * @param indexName
     * @param type
     * @param query
     * @param pageNum
     * @param pageSize
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> Page<T> search(String indexName,String[] type,String query,int pageNum,int pageSize,Class<T> clazz){
        try {
            return client.search(indexName, type, query, pageNum, pageSize, clazz);
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} query:{} pageNum:{} pageSize:{} clazz:{}"
                ,indexName,type,query,pageNum,pageSize,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return null;
        }
    }

    public static <T> Page<T> search(String indexName,String type,String query,int pageNum,int pageSize,Class<T> clazz){
        try {
            return client.search(indexName, type, query, pageNum, pageSize, clazz);
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} query:{} pageNum:{} pageSize:{} clazz:{}"
                ,indexName,type,query,pageNum,pageSize,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return null;
        }
    }

    /**
     * 搜索 可以设置搜索字段
     * @param indexName
     * @param type
     * @param fields 搜索的字段
     * @param query
     * @param pageNum
     * @param pageSize
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> Page<T> search(String indexName,String type,String[] fields,String query,int pageNum,int pageSize,Class<T> clazz){
        try {
            return client.search(indexName, type,fields, query, pageNum, pageSize, clazz);
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} query:{} pageNum:{} pageSize:{} clazz:{}"
                ,indexName,type,query,pageNum,pageSize,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return null;
        }
    }
    public static <T> List<T> search(String indexName,String[] types,String[] fields,String query,
                                     Class<T> clazz,boolean needHighLighter){
        try {
            return client.search(indexName, types,fields, query, clazz,needHighLighter);
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} query:{}  clazz:{}"
                ,indexName,types,query,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return null;
        }
    }

    /**
     * 范围搜索
     * @param indexName
     * @param type
     * @param filter
     * @param from
     * @param to
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> searchRange(String indexName,String[] type,String filter,Object from,Object to,Class<T> clazz){
        try {
            return client.searchRange(indexName, type, filter, from, to, clazz);
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} filter:{} from:{} to:{} clazz:{}"
                ,indexName,type,filter,from,to,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return new ArrayList<>();
        }
    }
    public static <T> List<T> searchRange(String indexName,String type,String filter,Object from,Object to,Class<T> clazz){
        try {
            List<T> list = client.searchRange(indexName, type, filter, from, to,clazz);
            return list;
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} filter:{} from:{} to:{} clazz:{}"
                ,indexName,type,filter,from,to,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return new ArrayList<>();
        }
    }
    public static <T> List<T> searchRange(String indexName,String[] type,Class<T> clazz,RangeBean... rangeBeans){
        try {
            List<T> list = client.searchRange(indexName,type,clazz,rangeBeans);
            return list;
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} rangeBeans:{} clazz:{}"
                ,indexName,type,rangeBeans,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return new ArrayList<>();
        }
    }
    public static <T> List<T> searchRange(String indexName,String type,Class<T> clazz,RangeBean... rangeBeans){
        try {
            List<T> list = client.searchRange(indexName,type,clazz,rangeBeans);
            return list;
        }catch (Exception e){
            logger.error("搜索失败 indexName:{} type:{} rangeBeans:{}  clazz:{}"
                ,indexName,type,rangeBeans,clazz);
            logger.error(e.getMessage(),e.fillInStackTrace());
            return new ArrayList<>();
        }
    }



}
